package jee.boot.common.basic;

import jee.boot.common.utils.Reflections;
import jee.boot.common.utils.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Service基类
 */

public abstract class TreeService<D extends TreeDao<T>, T extends TreeEntity<T>> extends CrudService<D, T> {
    public static final String TREE_ROOT_ID = "root_id";

    @Override
    public void save(T entity) {
        // 如果没有设置父节点，则代表为跟节点
        if (entity.getParent() == null) {
            entity.setParent(getParentRoot());
            entity.setLevel(entity.getParent().getLevel() + 1);
        } else {
            T p = super.get(entity.getParent());
            if(p==null){
                p=getParentRoot();
            }
            entity.setParent(p);
            entity.setLevel(p.getLevel() + 1);
        }
        // 设置新的父节点串
        entity.setParentIds(entity.getParent().getParentIds() + entity.getParent().getId() + ",");
        // 保存实体
        super.save(entity);


    }

    @Override
    public void update(T entity) {
        // 如果没有设置父节点，则代表为跟节点
        if (entity.getParent() == null) {
            entity.setParent(getParentRoot());
            entity.setLevel(entity.getParent().getLevel() + 1);
        } else {
            T p = super.get(entity.getParent());
            if(p==null){
                p=getParentRoot();
            }
            entity.setLevel(p.getLevel() + 1);
            entity.setParent(p);
        }
        // 获取修改前的parentIds，用于更新子节点的parentIds
        String oldParentIds = entity.getParentIds();
        // 设置新的父节点串
        entity.setParentIds(entity.getParent().getParentIds() + entity.getParent().getId() + ",");
        // 更新实体
        super.update(entity);
        // 更新子节点 parentIds
        T o = null;
        try {
            Class<T> entityClass = Reflections.getClassGenricType(getClass(), 1);
            o = entityClass.newInstance();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new ServiceException();
        }
        o.setParentIds("%"+entity.getId()+"%");
        List<T> list = dao.findByParentIdsLike(o);
        for (T e : list) {
            if (e.getParentIds() != null && oldParentIds != null) {
                // 这里好像有个问题,level怎么设置? 待定..
                e.setParentIds(e.getParentIds().replace(oldParentIds, entity.getParentIds()));
                dao.updateParentIds(e);
            }
        }

    }

    /**
     * 删除数据
     *
     * @param entity
     */
    public void delete(T entity) {
        dao.delete(entity);
        // 删除所有子节点
        entity.setParentIds("%"+entity.getId()+"%");
        List<T> list = dao.findByParentIdsLike(entity);
        if (list != null && !list.isEmpty()) {
            for (T del : list) {
                dao.delete(del);
            }
        }
    }

    /**
     * 建树
     *
     * @param list
     * @return
     */
    public List<T> buildTree(List<T> list) {
        List<T> retList = new ArrayList<T>();
        for (T child : list) {
            boolean hasParent = false;
            for (T parent : list) {



                if (child.getParent()!=null && StringUtils.equals(child.getParent().getId(), parent.getId())) {
                    parent.getChildren().add(child);
                    hasParent = true;
                }
            }
            if (!hasParent) {
                retList.add(child);
            }
        }
        sort(retList);// 排序
        return retList;
    }


    /**
     * 预留接口，用户更新子节前调用
     *
     * @param childEntity
     */
    protected void preUpdateChild(T entity, T childEntity) {

    }

    /**
     * 排序
     *
     * @param list
     */
    protected void sort(List<T> list) {
        if (list != null && !list.isEmpty()) {
            Collections.sort(list, new Comparator<T>() {
                public int compare(T a, T b) {
                    Integer sorta = a.getSort() == null ? 0 : a.getSort();
                    Integer sortb = b.getSort() == null ? 0 : b.getSort();
                    return sorta.compareTo(sortb);
                }
            });
            for (T child : list) {
                sort(child.getChildren());
            }
        }
    }

    /**
     * get一个虚拟的根节点,节点id为root_id
     * @return
     */
    protected T getParentRoot() {
        Class<T> entityClass = Reflections.getClassGenricType(getClass(), 1);
        T parentEntity = null;
        try {
            parentEntity = entityClass.getConstructor(String.class).newInstance(TREE_ROOT_ID);
            parentEntity.setParentIds(StringUtils.EMPTY);
            parentEntity.setLevel(0);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new ServiceException();
        }
        return parentEntity;
    }


}
